package com.ahyesyesteam.aicarfaultrepair.service.impl;

import com.ahyesyesteam.aicarfaultrepair.mapper.SolutionMapper;
import com.ahyesyesteam.aicarfaultrepair.mapper.SolutionUserLikeRelationMapper;
import com.ahyesyesteam.aicarfaultrepair.pojo.EsSolution;
import com.ahyesyesteam.aicarfaultrepair.pojo.Solution;
import com.ahyesyesteam.aicarfaultrepair.pojo.SolutionUserLikeRelation;
import com.ahyesyesteam.aicarfaultrepair.service.IEsSolutionService;
import com.ahyesyesteam.aicarfaultrepair.service.ISolutionService;
import com.ahyesyesteam.aicarfaultrepair.util.Response;
import com.ahyesyesteam.aicarfaultrepair.util.UserThreadLocal;
import com.ahyesyesteam.aicarfaultrepair.vo.params.LoginParam;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author SSQ
 * @since 2022-06-17
 */
@Service
public class SolutionServiceImpl extends ServiceImpl<SolutionMapper, Solution> implements ISolutionService {


    @Autowired
    SolutionMapper solutionMapper;

    @Autowired
    SolutionUserLikeRelationMapper solutionUserLikeRelationMapper;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    IEsSolutionService iEsSolutionService;

    @Override
    public List<Solution> getHotList(int limit){
        LambdaQueryWrapper<Solution> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Solution::getViewCount);
        queryWrapper.select(Solution::getId,Solution::getTitle);
        queryWrapper.last("limit "+limit );
        List<Solution> hots = solutionMapper.selectList(queryWrapper);
        return hots;
    }

    @Override
    public boolean saveSolutionInDBAndEs(String problem,String answer){
        try{
            Solution solution = new Solution();
            solution.setViewCount(0);
            solution.setLikeCount(0);
            solution.setCommentCount(0);
            solution.setCreateDate(LocalDateTime.now());
            solution.setTitle(problem);
            solution.setContent(answer);
            this.save(solution);

            EsSolution esSolution = new EsSolution();
            BeanUtils.copyProperties(solution,esSolution);
            iEsSolutionService.save(esSolution);
            return true;
        }catch (Exception e){
            System.out.println(e);
            return false;
        }
    }

    @Override
    public List<Solution> selectSolutionList(int page, int size, String key) {
        // 第一个参数是页数page，第二个参数是每页数据数量pageSize
        Pageable pageable = PageRequest.of(page, size);

        //多条件查询
        //只要满足一个条件就可以
        BoolQueryBuilder boolQueryBuilder= QueryBuilders.boolQuery()
                .should(QueryBuilders.matchQuery("title",key))
                .should(QueryBuilders.matchQuery("content",key));
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withHighlightFields(
                        new HighlightBuilder.Field("title")
                        ,new HighlightBuilder.Field("content"))
                .withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:red'>").postTags("</span>"))
                .withPageable(pageable)
                .build();
        SearchHits<EsSolution> search = elasticsearchRestTemplate.search(searchQuery, EsSolution.class);
        List<SearchHit<EsSolution>> searchHits = search.getSearchHits();
        List<EsSolution>esSolutions=new LinkedList<>();
        for(SearchHit<EsSolution> searchHit:searchHits){
            esSolutions.add(searchHit.getContent());
        }

        List<Solution> solutionList = esSolutions.stream()
          .filter((item)->{return this.getById(item.getId())!= null;})
          .map((item)->{
            Solution solution = this.getById(item.getId());
            solution.setContent(item.getContent());
            solution.setTitle(item.getTitle());
            return solution;
        }).collect(Collectors.toList());
        return solutionList;
    }

    @Override
    public void updateViewCount(Long solutionId){
        Solution solution = solutionMapper.selectById(solutionId);
        int viewCount = solution.getViewCount();
        Solution solutionUpdate = new Solution();
        solutionUpdate.setViewCount(viewCount+1);
        LambdaUpdateWrapper<Solution> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Solution::getId,solution.getId());
        updateWrapper.eq(Solution::getViewCount,viewCount);
        solutionMapper.update(solutionUpdate,updateWrapper);
    }

    @Override
    @Transactional
    public void likeSolution(Long solutionId){
        Solution solution = solutionMapper.selectById(solutionId);
        int likeCount = solution.getLikeCount();
        Solution solutionUpdate = new Solution();
        Long userId = UserThreadLocal.get().getId();
        LambdaQueryWrapper<SolutionUserLikeRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SolutionUserLikeRelation::getUserId,userId);
        queryWrapper.eq(SolutionUserLikeRelation::getSolutionId,solutionId);
        if(solutionUserLikeRelationMapper.selectOne(queryWrapper) != null){
            solutionUpdate.setViewCount(likeCount-1);
            LambdaUpdateWrapper<Solution> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Solution::getId,solution.getId());
            solutionMapper.update(solutionUpdate,updateWrapper);
            solutionUserLikeRelationMapper.delete(queryWrapper);
        }
        else
        {
            solutionUpdate.setViewCount(likeCount+1);
            LambdaUpdateWrapper<Solution> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Solution::getId,solution.getId());
            solutionMapper.update(solutionUpdate,updateWrapper);
            SolutionUserLikeRelation solutionUserLikeRelation = new SolutionUserLikeRelation();
            solutionUserLikeRelation.setSolutionId(solutionId);
            solutionUserLikeRelation.setUserId(userId);
            solutionUserLikeRelationMapper.insert(solutionUserLikeRelation);
        }
    }
}
